// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0

// Verify that the init callback is invoked in the correct order

import { ExportedGlobal } from "../../helper_components/export_globals.slint";

export global InitOrder := {
    property <string> observed-order: "start";
}

Sub1 := Rectangle {
    init => {
        InitOrder.observed-order += "|sub1";
    }
}

Sub2 := Rectangle {
    init => {
        InitOrder.observed-order += "|sub2";
    }
}

SubSub := Rectangle {
    init => {
        InitOrder.observed-order += "|subsub";
    }
}

Sub3 := Rectangle {
    property <string> some-value: "should-not-show-up";
    init => {
        InitOrder.observed-order += some-value;
    }
    SubSub {}
}

Container := Rectangle {
    in property <string> name-inside: "container";
    init => {
        InitOrder.observed-order += "|" + self.name-inside;
    }
    @children
}

InsideRepeater := Rectangle {
    property <int> index;
    init => {
        InitOrder.observed-order += "(i" + self.index + ")";
    }
    @children
}

TestCase := Rectangle {
    width: 300phx;
    height: 300phx;
    init => {
        InitOrder.observed-order += "|root";
        ExportedGlobal.foo += 1;
    }
    Sub1 {
        init => {
            InitOrder.observed-order += "|sub1-use-site";
        }
    }
    Sub2 {
    }
    Sub3 {
        some-value: "|sub3";
    }

    Container {
        property <string> name-outside: "container-instantiation";
        init => {
            InitOrder.observed-order += "|" + self.name-outside;
        }
    }

    Rectangle {
        init => {
            InitOrder.observed-order += "|element";
        }
    }

    for i in 2: InsideRepeater {
        index: i;
        init => {
            InitOrder.observed-order += "|repeater";
            InitOrder.observed-order += i;
        }
        Rectangle {}
    }

    property <string> test_global_prop_value: InitOrder.observed-order;

    property <string> expected_static_order: "start|sub1|sub2|subsub|sub3|container|root|sub1-use-site|container-instantiation|element";

    property <bool> test: InitOrder.observed-order == expected_static_order;
}

/*
```rust
let instance = TestCase::new().unwrap();

assert!(instance.get_test());
slint_testing::send_mouse_click(&instance, 5., 5.);
assert_eq!(instance.global::<InitOrder<'_>>().get_observed_order(), instance.get_expected_static_order() + "|repeater0(i0)|repeater1(i1)");
```

```cpp
auto handle = TestCase::create();
const TestCase &instance = *handle;
assert(instance.get_test());
slint_testing::send_mouse_click(&instance, 5., 5.);
assert_eq(instance.global<InitOrder>().get_observed_order(),  instance.get_expected_static_order() + "|repeater0(i0)|repeater1(i1)");
```


```js
var instance = new slint.TestCase({});
assert(instance.test);
slintlib.private_api.send_mouse_click(instance, 5., 5.);
assert.equal(instance.test_global_prop_value,  instance.expected_static_order + "|repeater0(i0)|repeater1(i1)");
```


*/
